#include "task.h"
#include <QDebug>
#include <QMutex>
#include <snmp_dev.h>
//#include <winsock2.h>
#include <snmp_pp/oid.h>
#include <snmp_pp/snmp_pp.h>

using namespace  Snmp_pp;

#define SYSDESCR          "1.3.6.1.2.1.1.1.0" //设备描述（只读）

QMutex Task::s_mutex;
static Pdu g_pdu;
snmp_version version = version2c; // default is v2c
int retries  = 1;                 // default retries is 1
int timeout  = 100;               // default is 1 second
u_short port = 161;               // default snmp port is 161
OctetStr community("public");     // community name

Task::Task(QString ip, QString community, QList<QString> oids)
{
    m_strIp = ip;
    m_strCommunity = community;
    m_oids = oids;

    Snmp::socket_startup();
}

Task::~Task()
{
    Snmp::socket_cleanup();
}

void Task::run()
{
    qDebug() << QThread::currentThreadId() << "start";

    UdpAddress address(m_strIp.toStdString().data());
    if (!address.valid())
    {
        qDebug() << "Invalid Address or DNS Name, " << "\n";
        return;
    }
    address.set_port(port);

    int status;
    Snmp snmp(status, 0, (address.get_ip_version() == Address::version_ipv6));
    if (status != SNMP_CLASS_SUCCESS)
    {
        qDebug() << "SNMP++ Session Create Fail, " << snmp.error_msg(status) << "\n";
        return;
    }

    CTarget ctarget(address);
    ctarget.set_version(version);
    ctarget.set_retry(retries);
    ctarget.set_timeout(timeout);
    ctarget.set_readcommunity(community);

    Vb vb[m_oids.size()];
    for(int i = 0; i < m_oids.size(); ++i)
    {
        vb[i].set_oid(m_oids[i].toStdString().data());
    }

    QMutexLocker lock(&this->s_mutex);
    g_pdu.clear();
    g_pdu.set_vblist(vb,m_oids.size());

    if((status = snmp.get(g_pdu, ctarget)) != SNMP_CLASS_SUCCESS)
    {
        qDebug() << snmp.error_msg(status);
    }
    else
    {
       g_pdu.get_vblist(vb,m_oids.size());
       for(int i=0; i < m_oids.size(); i++)
       {
           QString strCnt = "oid:" + QString::fromStdString(vb[i].get_printable_oid())
                   + " value:" + vb[i].get_printable_value();
           qDebug() << strCnt << endl;
           emit sigOidContent(strCnt);
       }
    }

    qDebug() << QThread::currentThreadId() << "end";
}

void Task::setOidValue(const QString &str)
{
    UdpAddress address("127.0.0.1");
    if (!address.valid())
    {
        qDebug() << "Invalid Address or DNS Name\n";
    }
    Oid oid(SYSDESCR);
    snmp_version version=version1;                  // default is v1
    int retries=1;                                  // default retries is 1
    int timeout=100;                                // default is 1 second
    u_short port=161;                               // default snmp port is 161
    OctetStr community("public");                   // community name
    OctetStr get_community;
    get_community = community;
    int status;
    Snmp snmp(status, 0, (address.get_ip_version() == Address::version_ipv6));

    if (status != SNMP_CLASS_SUCCESS)
    {
        qDebug() << "SNMP++ Session Create Fail, " << snmp.error_msg(status) << "\n";
        return;
    }

    address.set_port(port);
    CTarget ctarget(address);             // make a target using the address
    ctarget.set_version(version);         // set the SNMP version SNMPV1 or V2
    ctarget.set_retry(retries);           // set the number of auto retries
    ctarget.set_timeout(timeout);         // set timeout
    ctarget.set_readcommunity(get_community); // set the read community name
    ctarget.set_writecommunity(community);// set the write community name
    //-------[ issue the request, blocked mode ]-----------------------------
    std::cout << "SNMP++ Set to " << " Retries=" << retries<< " Timeout=" << timeout * 10 <<"ms";
    std::cout << " SET-community=" << community.get_printable()<< " GET-community=" << get_community.get_printable();
    SnmpTarget *target;
    target = &ctarget;

    QMutexLocker lock(&this->s_mutex);
    g_pdu.clear();
    Vb vb;
    vb.set_oid(oid);
    vb.set_value("123456");
    vb.set_oid(oid);
    g_pdu += vb;
    status = snmp.set(g_pdu, *target);
    qDebug() << "Set Status = " << snmp.error_msg(status) << "\n";
}
